#include "pattern.h"

using namespace tp1;

Pattern::Pattern(float radius,float angle,int qObliqueCylinders,float radiusCylinders,int sidesCylinders)
	:Object3D(2*radiusCylinders)
{
	// Angulo que forma el patron y el radio del patron.
	m_radius = radius;
	m_angle = angle;
	m_qObliqueCylinders = qObliqueCylinders;

	// Radio y cantidad de lados de los cilindros que integran el patron.
	m_radiusCylinders = radiusCylinders;
	m_sidesCylinders = sidesCylinders;

	// Coeficiente de altura de los cilindros oblicuos 
	// (dado que se trata de un triangulo isosceles).
	m_coefHeightCyl = 2.0f*sinf(0.5f*Mathematic::toRadians(m_angle));
	// Coeficiente del radio de cada uno de los cilindros oblicuos.
	m_coefRadiusCyl = m_radius/(float)m_qObliqueCylinders;

	// Cilindro que se usa para formar el patron.
	// En principio le seteo la altura en 1.
	m_cylinder = new Cylinder(m_radiusCylinders,1,m_sidesCylinders);
}


Pattern::~Pattern()
{
	delete m_cylinder;
}

float Pattern::GetAngle()
{
	return m_angle;
}

float Pattern::GetRadius()
{
	return m_radius;
}

void Pattern::SetRadius(float radius)
{
	m_radius = radius;

	m_coefRadiusCyl = m_radius/(float)m_qObliqueCylinders;
}

void Pattern::SetAngle(float angle)
{
	m_angle = angle;

	// Coeficiente de altura de los cilindros oblicuos 
	// (dado que se trata de un triangulo isosceles).
	m_coefHeightCyl = 2.0f*sinf(0.5f*Mathematic::toRadians(m_angle));
	// Coeficiente del radio de cada uno de los cilindros oblicuos.
}

void Pattern::Render()
{
	int i = 0;
	
	
	
	// Cilindro que esta sobre el eje.
	m_cylinder->SetHeight(m_radius);
	glPushMatrix();		
		m_cylinder->Rotate(90,0,1,0);
		m_cylinder->Render();
	glPopMatrix();
	++i;

	glPushMatrix();
		// Cilindros oblicuos
		for(i; i<= m_qObliqueCylinders; i++)
		{
			// Altura del cilindro oblicuo i.
			float height_i = m_coefHeightCyl*(m_coefRadiusCyl*i);
			m_cylinder->SetHeight(height_i);

			m_cylinder->Translate(m_coefRadiusCyl,0,0);
			glPushMatrix();
				m_cylinder->Rotate(90-(180.0f-m_angle)/2.0f,0,-1,0);
				m_cylinder->Render();		
			glPopMatrix();
		}
	glPopMatrix();
		
	

}

TrianglePattern::TrianglePattern(float base,float height,int qObliqueCyls,float radiusCylinders,int sidesCylinders)
	:Object3D(radiusCylinders)
{
	// Base (lado desigual) y altura del triangulo que es de tipo isosceles.
	m_base = base;
	m_height = height;

	m_radiusCylinders = radiusCylinders;
	m_sidesCylinders = sidesCylinders;

	float angle = 2*atanf(m_base/(2.0f*m_height));
	float radius = m_height/cos(angle/2.0f);

	// lo paso a grados sexagesimales.
	angle = Mathematic::toDegrees(angle);

	m_pattern = new Pattern(radius,angle,qObliqueCyls,m_radiusCylinders,m_sidesCylinders);
	m_cylinder = new Cylinder(m_radiusCylinders,radius,m_sidesCylinders);	
}

TrianglePattern::~TrianglePattern()
{
	delete m_pattern;
	delete m_cylinder;
}

void TrianglePattern::Render()
{
	glPushMatrix();
		Rotate(90+(m_pattern->GetAngle()/2.0f),0,1,0);
		m_pattern->Render();		
	glPopMatrix();

	// Cilindro que cierra
	glPushMatrix();
		Rotate(180-(m_pattern->GetAngle()/2.0f),0,1,0);
		m_cylinder->Render();
	glPopMatrix();
}